#include "include/trading_system.hpp"
#include "include/tools/readAndWrite.hpp"
#include "include/tools/Hash.hpp"
#include <QDebug>
#include <qdebug.h>

TradingSystem::TradingSystem(QObject *parent)
    : QObject(parent), m_isLoggedIn(false) {
  m_marketDataManager = new MarketDataManager(this);

  // 连接信号槽，当市场数据更新时更新用户账户中的股票价格
  connect(m_marketDataManager, &MarketDataManager::marketUpdated, this,
          &TradingSystem::updateAccountStockPrices);
}

TradingSystem::~TradingSystem() {
  // 保存用户数据
  saveUserData();

  if (m_marketDataManager) {
    m_marketDataManager->stopSimulation();
  }
}

bool TradingSystem::initialize() {
  // 加载股票数据
  if (!m_marketDataManager->loadStocks()) {
    qDebug() << "加载股票数据失败";
    return false;
  }

  // 加载用户数据
  if (!loadUserData()) {
    qDebug() << "加载用户数据失败";
    return false;
  }

  // 启动市场模拟
  m_marketDataManager->startSimulation();

  return true;
}

bool TradingSystem::registerUser(const QString &username,
                                 const QString &password,
                                 double initialBalance) {
  // 检查用户名是否已存在
  if (m_users.contains(username)) {
    qDebug() << "用户名已存在:" << username;
    return false;
  }

  // 创建用户和账户
  m_users.insert(username, User(username, password));
  qDebug() << "创建用户和账户:用户密码哈希:"
           << QString::fromStdString(password.toStdString());
  m_accounts.insert(username, UserAccount(username, initialBalance));

  qDebug() << "用户注册成功:" << username;

  // 保存用户数据
  saveUserData();

  emit userRegistered(username);

  return true;
}

bool TradingSystem::loginUser(const QString &username,
                              const QString &password) {
  // 检查用户是否存在
  if (!m_users.contains(username)) {
    qDebug() << "用户不存在:" << username;
    return false;
  }

  // 验证密码
  // Ensure calculateHash is declared and included from Hash.hpp
  QString hashedPassword =
      QString::fromStdString(calculateHash(password.toStdString()));
  if (!m_users[username].checkPassword(hashedPassword)) {
    qDebug() << "密码错误:" << username;
    return false;
  }

  // 登录成功
  m_currentUsername = username;
  m_isLoggedIn = true;

  qDebug() << "用户登录成功:" << username;

  emit userLoggedIn(username);

  return true;
}

void TradingSystem::logoutUser() {
  if (m_isLoggedIn) {
    // 保存用户数据
    saveUserData();

    QString oldUsername = m_currentUsername;
    m_currentUsername.clear();
    m_isLoggedIn = false;

    qDebug() << "用户登出成功:" << oldUsername;

    emit userLoggedOut();
  }
}

bool TradingSystem::isLoggedIn() const { return m_isLoggedIn; }

UserAccount *TradingSystem::getCurrentAccount() {
  if (m_isLoggedIn && m_accounts.contains(m_currentUsername)) {
    return &m_accounts[m_currentUsername];
  }
  return nullptr;
}

MarketDataManager *TradingSystem::getMarketDataManager() {
  return m_marketDataManager;
}

void TradingSystem::updateAccountStockPrices() {
  if (!m_isLoggedIn) {
    return;
  }

  UserAccount *account = getCurrentAccount();
  if (!account) {
    return;
  }

  // 更新用户持仓中的股票价格
  for (auto &position : account->getPositions()) {
    Stock *stock = m_marketDataManager->findStock(position.stockCode);
    if (stock) {
      position.currentPrice = stock->price;
    }
  }

  emit accountUpdated();
}

bool TradingSystem::loadUserData(const QString &filePath) {
  nlohmann::json usersJson;

  try {
    // 使用 readAndWrite.hpp 中的函数读取 JSON 文件
    std::string stdFilePath = filePath.toStdString();
    usersJson = read_from_file(stdFilePath, usersJson);

    // 清空现有用户数据
    m_users.clear();
    m_accounts.clear();

    // 解析用户数据
    if (usersJson.contains("users") && usersJson["users"].is_array()) {
      auto usersArray = usersJson["users"];

      for (const auto &userJson : usersArray) {
        if (userJson.contains("username") && userJson.contains("password") &&
            userJson.contains("balance")) {

          QString username =
              QString::fromStdString(userJson["username"].get<std::string>());
          QString password =
              QString::fromStdString(userJson["password"].get<std::string>());
          double balance = userJson["balance"].get<double>();

          // 创建用户和账户
          m_users.insert(username, User(username, password));
          m_accounts.insert(username, UserAccount(username, balance));

          // 设置持仓数据（如果有）
          if (userJson.contains("portfolio") &&
              userJson["portfolio"].is_array()) {
            auto portfolioArray = userJson["portfolio"];

            for (const auto &posJson : portfolioArray) {
              if (posJson.contains("stockCode") &&
                  posJson.contains("stockName") && posJson.contains("shares") &&
                  posJson.contains("avgPrice")) {

                QString stockCode = QString::fromStdString(
                    posJson["stockCode"].get<std::string>());
                QString stockName = QString::fromStdString(
                    posJson["stockName"].get<std::string>());
                int shares = posJson["shares"].get<int>();
                double avgPrice = posJson["avgPrice"].get<double>();

                // 模拟买入操作以创建持仓
                m_accounts[username].buy(stockCode, stockName, shares,
                                         avgPrice);
              }
            }
          }
        }
      }

      qDebug() << "已加载" << m_users.size() << "个用户";
      return true;
    }
  } catch (const std::exception &e) {
    qDebug() << "加载用户数据失败:" << e.what();
  }

  return false;
}

bool TradingSystem::saveUserData(const QString &filePath) {
  try {
    nlohmann::json usersJson;
    nlohmann::json usersArray = nlohmann::json::array();
    for (auto it = m_users.begin(); it != m_users.end(); ++it) {
      const QString &username = it.key();
      qDebug() << "正在保存用户:" << username;
      if (!m_accounts.contains(username)) {
        continue;
      }

      const UserAccount &account = m_accounts[username];

      nlohmann::json userJson;
      userJson["username"] = username.toStdString();
      userJson["password"] = it.value().getPassword(); // 使用哈希存储密码

      userJson["balance"] = account.getBalance();

      // 添加持仓数据
      nlohmann::json portfolioArray = nlohmann::json::array();
      for (const auto &pos : account.getPositions()) {
        nlohmann::json posJson;
        posJson["stockCode"] = pos.stockCode.toStdString();
        posJson["stockName"] = pos.stockName.toStdString();
        posJson["shares"] = pos.shares;
        posJson["avgPrice"] = pos.avgPrice;

        portfolioArray.push_back(posJson);
      }

      userJson["portfolio"] = portfolioArray;

      usersArray.push_back(userJson);
    }

    usersJson["users"] = usersArray;

    // 使用 readAndWrite.hpp 中的函数写入 JSON 文件
    std::string stdFilePath = filePath.toStdString();
    write_to_file(stdFilePath, usersJson);

    qDebug() << "已保存" << m_users.size() << "个用户";
    return true;
  } catch (const std::exception &e) {
    qDebug() << "保存用户数据失败:" << e.what();
  }

  return false;
}
